class FormatLog():
    def __init__(self, data):
        self.data = data
        # 提取表头
        self.keyHeader = self.data[0].keys()
        self.keyMaxLen = self.__get_keyMaxLen()
        self.complement_length = 4

    def __get_keyMaxLen(self):
        # 存放每列的最大长度
        keyMaxLen = {}
        for item in self.data:
            for i, h in enumerate(self.keyHeader):
                # 计算每个属性对应的最大长度
                maxLen = max(len(h), len(str(item[h])))
                if keyMaxLen.get(h, None):
                    maxLen = max(maxLen, keyMaxLen[h])
                keyMaxLen[h] = maxLen
        return keyMaxLen

    def formatGroup(self, group):
        tmp_str = ""
        for item in group:
            for i, h in enumerate(self.keyHeader):
                itemLen = self.keyMaxLen.get(h, str(h)) + self.complement_length
                # 补空位并居中
                s = str(item[h]).center(itemLen, '-' if item[h] == '-' else ' ')
                icon = '|'
                if item[h] == '-':
                    icon = '+'
                s = (icon if i == 0 else '') + s[1:len(s)] + icon
                tmp_str += s
            tmp_str += "\n"
        return tmp_str

    def format_tag(self):
        # 占位项
        tag = {}
        for i, h in enumerate(self.keyHeader):
            tag[h] = '-'
        # 前后添上
        self.data.insert(0, tag)
        self.data.append(tag)
        # 第一行需要先单独打印出来
        return self.formatGroup([tag])

    def format_header(self):
        tmp_str = ""
        # 再单独打印表头
        for i, h in enumerate(self.keyHeader):
            # 留空位4
            itemLen = self.keyMaxLen.get(h, str(h)) + self.complement_length
            # 快捷居中并补空位  左对齐可使用 ljust之类
            s = h.center(itemLen)
            s = ('|' if i == 0 else '') + s[1:len(s)] + '|'
            tmp_str += s
        return tmp_str

    def transform(self):
        tag_str = self.format_tag()
        header_str = self.format_header()
        data_str = self.formatGroup(self.data)
        return tag_str + header_str + "\n" + data_str


